package com.shlh.saas.util;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 文件工具类
 */
@Slf4j
public class FileUtils {
    
    /**
     * 估算Excel文件大小（KB）
     * 根据记录数量估算Excel文件的大小，这是一个粗略估计
     * 假设每条记录平均占用500字节
     * 
     * @param recordCount 记录数量
     * @return 估计的文件大小（KB）
     */
    public static String estimateExcelSize(int recordCount) {
        // 基础Excel文件大小约为10KB
        double baseSize = 10.0;
        
        // 每条记录估计约占0.5KB
        double recordSize = recordCount * 0.5;
        
        // 总大小
        double totalSize = baseSize + recordSize;
        
        // 四舍五入到小数点后两位
        BigDecimal bd = new BigDecimal(totalSize).setScale(2, RoundingMode.HALF_UP);
        
        return bd.toString();
    }
    
    /**
     * 格式化文件大小，转换为B, KB, MB, GB等
     * 
     * @param size 文件大小（字节）
     * @return 格式化后的文件大小字符串
     */
    public static String formatFileSize(long size) {
        if (size <= 0) {
            return "0 B";
        }
        
        final String[] units = {"B", "KB", "MB", "GB", "TB", "PB", "EB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        
        // 计算并格式化文件大小
        BigDecimal bd = new BigDecimal(size / Math.pow(1024, digitGroups))
                .setScale(2, RoundingMode.HALF_UP);
        
        return bd.toString() + " " + units[digitGroups];
    }

    /**
     * 下载文件
     *
     * @param response 响应对象
     * @param filePath 文件路径
     */
    public static void downloadFile(HttpServletResponse response, String filePath) {
        try {
            File file = new File(filePath);
            
            // 检查文件是否存在
            if (!file.exists()) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.getWriter().write("文件不存在或已被删除");
                return;
            }
            
            // 获取文件名
            String fileName = file.getName();
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String encodedFilename = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFilename);
            response.setHeader("Content-Length", String.valueOf(file.length()));
            
            // 避免缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "0");
            
            // 使用缓冲流复制文件内容到响应输出流
            try (FileInputStream fis = new FileInputStream(file);
                 BufferedInputStream bis = new BufferedInputStream(fis);
                 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
                
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = bis.read(buffer)) != -1) {
                    bos.write(buffer, 0, bytesRead);
                }
                bos.flush();
            }
        } catch (Exception e) {
            log.error("下载文件失败: {}", e.getMessage(), e);
            try {
                response.reset();
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("text/plain;charset=UTF-8");
                response.getWriter().write("下载文件失败: " + e.getMessage());
            } catch (IOException ex) {
                log.error("设置错误响应失败: {}", ex.getMessage(), ex);
            }
        }
    }

    /**
     * 创建目录
     *
     * @param dirPath 目录路径
     * @return 目录对象
     */
    public static File createDirectory(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    /**
     * 获取资源文件
     *
     * @param filePath 文件路径
     * @return 资源对象
     * @throws MalformedURLException URL格式异常
     */
    public static Resource getFileAsResource(String filePath) throws MalformedURLException {
        Path path = Paths.get(filePath);
        return new UrlResource(path.toUri());
    }
} 